use std::ffi::c_void;

use core_graphics::{CGPoint, CGRect};
use foundation::{id, Class, NSArray, NSData, NSDictionary, NSString, NSUInteger, ObjCObject, NSURL};
use objc::{runtime::BOOL, sel, sel_impl};
use objc_derive::{selector_export, Alloc, Deref, GetObject, Message};

#[repr(transparent)]
#[derive(Clone, Message, GetObject, Alloc, Deref)]
pub struct UIDocumentPickerViewController(pub id);

impl UIDocumentPickerViewController {
  #[selector_export("initForOpeningContentTypes:")]
  pub fn init_for_opening_content_types(&self, content_types: NSArray) -> UIDocumentPickerViewController;

  #[selector_export("setDelegate:")]
  pub fn set_delegate(&self, delegate: id);
}

#[repr(transparent)]
#[derive(Clone, Message, GetObject, Alloc, Deref)]
pub struct UIApplication(pub id);

impl UIApplication {
  #[selector_export(UIApplication, "sharedApplication")]
  pub fn shared_application() -> UIApplication;

  #[selector_export("keyWindow")]
  pub fn key_window(&self) -> UIWindow;

  #[selector_export("openURL:options:completionHandler:")]
  pub fn open_url_options_completion_handler(&self, url: NSURL, options: NSDictionary, completion_handler: id);
}

#[repr(transparent)]
#[derive(Clone, Message, GetObject, Alloc, Deref)]
pub struct UIWindow(pub id);

impl UIWindow {
  #[selector_export("rootViewController")]
  pub fn root_view_controller(&self) -> UIViewController;

  #[selector_export("setRootViewController:")]
  pub fn set_root_view_controller(&self, root_view_controller: UIViewController);

  #[selector_export("initWithWindowScene:")]
  pub fn init_with_window_scene(&self, window_scene: id) -> Self;

  #[selector_export("makeKeyAndVisible")]
  pub fn make_key_and_visible(&self);
}

#[repr(transparent)]
#[derive(Clone, Message, GetObject, Alloc, Deref)]
pub struct UIViewController(pub id);

impl UIViewController {
  #[selector_export("presentViewController:animated:completion:")]
  pub fn present_view_controller_animated_completion(
    &self,
    view_controller_to_present: id,
    animated: bool,
    completion: *const c_void,
  );

  #[selector_export("view")]
  pub fn view(&self) -> UIView;

  #[selector_export("setView:")]
  pub fn set_view(&self, view: UIView);
}

#[repr(transparent)]
#[derive(Clone, Message, GetObject, Alloc, Deref)]
pub struct UIDocumentInteractionController(pub id);

impl UIDocumentInteractionController {
  #[selector_export(UIDocumentInteractionController, "interactionControllerWithURL:")]
  pub fn interaction_controller_with_url(url: NSURL) -> Self;

  #[selector_export("setDelegate:")]
  pub fn set_delegate(&self, delegate: id);

  #[selector_export("presentPreviewAnimated:")]
  pub fn present_preview_animated(&self, animated: bool) -> bool;
}

#[repr(transparent)]
#[derive(Clone, Message, GetObject, Alloc, Deref)]
pub struct UISceneConfiguration(pub id);

impl UISceneConfiguration {
  #[selector_export(UISceneConfiguration, "configurationWithName:sessionRole:")]
  pub fn configuration_with_name_session_role(name: NSString, session_role: NSString) -> Self;

  #[selector_export("setDelegateClass:")]
  pub fn set_delegate_class(&self, delegate_class: Class);

  #[selector_export("hash")]
  pub fn hash(&self) -> NSUInteger;
}

#[repr(transparent)]
#[derive(Clone, Message, GetObject, Alloc, Deref)]
pub struct UIView(pub id);

impl UIView {
  #[selector_export("setBackgroundColor:")]
  pub fn set_background_color(&self, background_color: UIColor);

  #[selector_export("addSubview:")]
  pub fn add_subview(&self, view: UIView);

  #[selector_export("setTranslatesAutoresizingMaskIntoConstraints:")]
  pub fn set_translates_autoresizing_mask_into_constraints(&self, value: BOOL);

  #[selector_export("setFrame:")]
  pub fn set_frame(&self, frame: CGRect);
}

#[repr(transparent)]
#[derive(Clone, Message, GetObject, Alloc, Deref)]
pub struct UIColor(pub id);

impl UIColor {
  #[selector_export(UIColor, "systemBlueColor")]
  pub fn system_blue_color() -> Self;

  #[selector_export(UIColor, "whiteColor")]
  pub fn white_color() -> Self;

  #[selector_export(UIColor, "redColor")]
  pub fn red_color() -> Self;

  #[selector_export(UIColor, "yellowColor")]
  pub fn yellow_color() -> Self;

  #[selector_export(UIColor, "blackColor")]
  pub fn black_color() -> Self;
}

impl UIColor {
  #[selector_export("set")]
  pub fn set(&self);
}

#[repr(transparent)]
#[derive(Clone, Message, GetObject, Alloc, Deref)]
pub struct UILabel(pub id);

impl UILabel {
  #[selector_export("setText:")]
  pub fn set_text(&self, text: NSString) -> Self;

  #[selector_export("setCenter:")]
  pub fn set_center(&self, center: CGPoint) -> Self;

  #[selector_export("sizeToFit")]
  pub fn size_to_fit(&self) -> Self;
}

#[repr(transparent)]
#[derive(Clone, Message, GetObject, Alloc, Deref)]
pub struct UIImage(pub id);

impl UIImage {
  #[selector_export(UIImage, "imageWithContentsOfFile:")]
  pub fn image_with_contents_of_file(path: NSString) -> Self;

  #[selector_export("initWithData:")]
  pub fn init_with_data(&self, data: NSData) -> Self;

  #[selector_export(UIImage, "imageWithData:")]
  pub fn image_with_data(data: NSData) -> Self;
}

impl UIImage {
  #[selector_export("drawAtPoint:")]
  pub fn draw_at_point(&self, point: CGPoint) -> Self;

  #[selector_export("drawInRect:")]
  pub fn draw_in_rect(&self, rect: CGRect) -> Self;
}

#[repr(transparent)]
#[derive(Clone, Message, GetObject, Alloc, Deref)]
pub struct UIImageView(pub id);

impl UIImageView {
  #[selector_export("initWithImage:")]
  pub fn init_with_image(&self, image: UIImage) -> Self;
}
